/**
 * This class contains unit tests for validating the behavior of Apex classes
 * and triggers.
 *
 * Unit tests are class methods that verify whether a particular piece
 * of code is working properly. Unit test methods take no arguments,
 * commit no data to the database, and are flagged with the testMethod
 * keyword in the method definition.
 *
 * All test methods in an organization are executed whenever Apex code is deployed
 * to a production organization to confirm correctness, ensure code
 * coverage, and prevent regressions. All Apex classes are
 * required to have at least 75% code coverage in order to be deployed
 * to a production organization. In addition, all triggers must have some code coverage.
 * 
 * The @isTest class annotation indicates this class only contains test
 * methods. Classes defined with the @isTest annotation do not count against
 * the organization size limit for all Apex scripts.
 *
 * See the Apex Language Reference for more information about Testing and Code Coverage.
 */
@isTest(SeeAllData = true)
private class AccountStandardControllerTestClass {

        static testMethod void testMyController() {
        
        
        
        //Navigation auxiliar for this test class
        PageReference nextPage;
        
        //We say that will start in EmployeeStep1 Page
        Test.setCurrentPage(Page.EmployeeStep1);
        AccountStandardController controller = new AccountStandardController();
        
        controller.checkEmployee();
        
        //Just cover the code for goToStep1, goToStep2 and goToStep3 methods
        controller.goToStep1();
        controller.goToStep2();
        controller.goToStep3();
        
        //Just cover the get and set methods
        controller.getpersonAccount();
        controller.getContact();
        controller.getRelatives();
        controller.getRelative();
        controller.getCommute();
        controller.getCommutes();
        controller.getEducation();
        controller.getEducations();
        controller.getHistory();
        controller.getHistories();
        controller.getAttFace();
        controller.getAttBody();
        controller.getMessageFacePhoto();
        controller.getMessageBodyPhoto();
        controller.getStyleFacePhoto();
        controller.getStyleBodyPhoto();
        controller.getFileNameForFacePhoto();
        controller.getFileNameForBodyPhoto();
        controller.setFileNameForFacePhoto('');
        controller.setFileNameForBodyPhoto('');
        controller.getCourses();
        
        //Create an Account and Contact Object to use as test.
        Account testAccount = new Account();
        Contact testContact = new Contact();
        Account testAccountEmpty = new Account();
        Contact testContactEmpty = new Contact();
        
        //Fill the fields of each object
        testAccount.RecordTypeId='012E0000000cDcN';
        testContact.Salutation = 'Mr';
        testAccount.Height__c = 1.80;
        testContact.FirstName = 'An account test';
        testAccount.Weight__c = 70;
        testContact.LastName ='Last name for account';
        testContact.Email='test@test.com';
        testAccount.CurrencyIsoCode ='USD';
        //testAccount.Birthdate__c = Date.parse('24/10/1990');
        testAccount.Willing_to_travel__c = true;
        testAccount.Marital_Status__c = 'Single';
        testAccount.States_where_I_have_family__c = 'AGUASCALIENTES';
        
        //Let´s sure that method saveEmployee doesn´t work if we send an empty object Account and Contact
        //In this way, we ensure that will cover the code that sends the exception
        controller.personAccount = testAccountEmpty;
        controller.contact = testContactEmpty;
        controller.saveEmployee();
        
        //First, We produce an exception in age to cover the message of exception in method saveRelative()
        //We try to insert an employee that is younger than 18
        testAccount.Birthdate__c = Date.parse('01/01/2012');
        controller.personAccount = testAccount;
        controller.contact = testContact;
        //System.debug('///////////////////////Fecha antes de guardar: '+testAccount.Birthdate__c);
        controller.saveEmployee();
        
        ApexPages.currentPage().getParameters().put('id',testAccount.Id);
        AccountStandardController controllerConstructor = new AccountStandardController();
        
        //We produce an exception to cover the message of exception in method finish()
        Account accEmpty;
        controller.personAccount = accEmpty;
        controller.finish();
                
        //Now, give a prefilled Account and Contact and we follow the perfect flow
        //Then assign the testAccount and testContact to the controller
        
        //We correct the birthdate that we modified to provocate the age exception
        testAccount.Birthdate__c = Date.parse('24/10/1990');
        
        controller.personAccount = testAccount;
        controller.contact = testContact;
        
        //Call the function saveEmployee that is in the controller and save the PageReference returned
        //in the nextPage variable
        nextPage=controller.saveEmployee();
        
        //Now, the current page is EmployeeStep2
        Test.setCurrentPage(nextPage);
        
        //Just cover the code for get Methods once testAccount is created
        controller.getRelatives();
        controller.getCommutes();
        controller.getEducations();
        controller.getHistories();
        
        //Produce an exception in method saveRelative and cover the code
        Employee_Relative_del__c relEmpty;
        controller.relative = relEmpty;
        controller.saveRelative();
        
        //Now create a relative to use in test
        Employee_relative_del__c testRelative = new Employee_Relative_del__c();
        Employee_relative_del__c testRelativeEmpty = new Employee_Relative_del__c();
        
        //testRelative.Employee__c = testAccount.Id;
        testRelative.Name = 'Relative test';
        testRelative.Relationship__c = 'Child';
        testRelative.Phone__c = '012345';
        testRelative.Occupation__c = 'Student';
        
        //Let´s sure that method saveRelative doesn´t work if we send an empty object Employee_relatice_del__c 
        //In this way, we ensure that will cover the code that sends the messages to the user
        System.debug('Objeto relative empty: ' +testRelativeEmpty);

		//We ensure that we cover the code that sends the messages to the user
		
		//First the message for the field Name 
		//ApexPages.addMessage(new Apexpages.Message(ApexPages.Severity.ERROR, 'Please. Enter a value in FullName field'));
        controller.relative = testRelativeEmpty;
        controller.saveRelative();
        
        //Then, the message for the field Relationship
        //ApexPages.addMessage(new Apexpages.Message(ApexPages.Severity.ERROR, 'Please. Select the relationship'));
        testRelativeEmpty.Name = 'Test21';
        controller.relative = testRelativeEmpty;
        controller.saveRelative();
        
        //Now, we follow the perfect flow
        //We say that the testRelative object corresponds to the controller
        controller.relative = testRelative;
        
        //Save the relative
        controller.saveRelative();
        
        //We produce an exception in method updateRelative to cover the code
        AccountStandardController.updateRelative('', 'Name', 'An account test 2');
        
        //Now, we update data of testRelative
        AccountStandardController.updateRelative(testRelative.Id, 'Name', 'An account test 2');
        AccountStandardController.updateRelative(testRelative.Id, 'Relationship__c', 'Child');
        AccountStandardController.updateRelative(testRelative.Id, 'Phone__c', '123456789');
        AccountStandardController.updateRelative(testRelative.Id, 'Occupation__c', 'Worker');
        
        //We produce an exception to cover the code of method deleteRelative()
  		//AccountStandardController.deleteRelative('');
        
        //Now, delete the relative correctly
        //AccountStandardController.deleteRelative(testRelative.Id);
        
        ApexPages.currentPage().getParameters().put('idRelativeToDelete',testRelative.Id);
        AccountStandardController.deleteRelative();
        
        //Now we go to the next Step in the wizard
        nextPage = controller.goToStep4();
        
        //Now, we specify the current page to Test Class
        Test.setCurrentPage(nextPage);
        
        //We are in step 4, where ther user introduces information about Address
        testAccount.BillingStreet='Test street';
        testAccount.BillingCity = 'Test city';
        testAccount.BillingState = 'Test state';
        testAccount.BillingPostalCode = '12345';
        
        //We move to the next Step. We are now in Step 5
        nextPage = controller.goToStep5();
        
        //Now, we specify the current page to Test Class
        Test.setCurrentPage(nextPage);
        
        //The step 5 is where the user introduces information about Commutes, so go ahead and create
        //a Commute object for testing
        
        //First, We produce an exception in method saveCommute and cover the code
        Commute__c comEmpty;
        controller.commute = comEmpty;
        controller.saveCommute();
        
        //Now, the normal flow
        Commute__c testCommute = new Commute__c();
        Commute__c testCommuteEmpty = new Commute__c();
        Store__c randomStore = [SELECT Id, Name FROM Store__c limit 1];
        System.debug('Random Store: '+randomStore);
        testCommute.Store__c = randomStore.Id;
        testCommute.Transfer_Time__c = 25;
        testCommute.Cost__c = 100;
        testCommute.Route__c = '14';
        
        //Let´s sure that method saveCommute doesn´t work if we send an empty object Commute__c 
        //In this way, we ensure that will cover the code that sends the messages to the user
        
        //First the message for Store 
        //ApexPages.addMessage(new Apexpages.Message(ApexPages.Severity.ERROR, 'Please. Select a value in Store Field'));
        controller.commute = testCommuteEmpty;
        controller.saveCommute();
        
        //Then the message for Transfer_Time
        //ApexPages.addMessage(new Apexpages.Message(ApexPages.Severity.ERROR, 'Please. Enter a value in Transfer Time field'));
        testCommuteEmpty.Store__c = randomStore.Id;
        controller.commute = testCommuteEmpty;
        controller.saveCommute();
        
        
        //We say that the testCommute object corresponds to the controller
        controller.commute = testCommute;

        //Save the commute
        controller.saveCommute();
        
        //We produce an exception in method updateCommute to cover the code
        AccountStandardController.updateCommute('', 'Store__c', 'Santa Fe');
        
        //Now we modify information about the commute we already saved
        AccountStandardController.updateCommute(testCommute.Id, 'Store__c', 'Santa Fe');
        AccountStandardController.updateCommute(testCommute.Id, 'Transfer_Time__c', '10');
        AccountStandardController.updateCommute(testCommute.Id, 'Cost__c', '5');
        AccountStandardController.updateCommute(testCommute.Id, 'Cost__c', '');
        AccountStandardController.updateCommute(testCommute.Id, 'Route__c', '15');
        
        //We produce an exception to cover the code of method deleteCommute()
  		//AccountStandardController.deleteCommute('');
        
        //Delete the commute correctly to cover the ABC code of commute in AccountStandardController
        //AccountStandardController.deleteCommute(testCommute.Id);
        ApexPages.currentPage().getParameters().put('idCommuteToDelete',testCommute.Id);
        AccountStandardController.deleteCommute();
        
        //Now we go to the next Step in te wizard
        nextPage = controller.goToStep6();
        
        //Specify the current page to the Test Class
        Test.setCurrentPage(nextPage);
        
        //In Step 6, the user introduces general, vestment and photography information. So go ahead and Let´s do it
        Position__c randomPosition = [SELECT Id FROM Position__c LIMIT 1];
        testAccount.Position__c = randomPosition.Id;
        testAccount.Current_Store__c = randomStore.Id;
        testAccount.Join_date__c = Date.parse('13/12/1990');
        testAccount.Coat__c = 'M';
        testAccount.Vest__c = 'M';
        testAccount.Pants__c = 'M';
        testAccount.Shirt__c = 'M';
        
        //Now we upload face and body photos
        
        //Create necessary variables for testing
      
        Attachment testAttachmentFace = new Attachment();
        Attachment testAttachmentBody = new Attachment();
        String facePhoto='This is the content for the attachment';
        String facePhotoUpdated='This is the content for the attachment which has been updated';
        String bodyPhoto='This is the content for the attachment';
        String bodyPhotoUpdated='This is the content for the attachment which has been updated';
        String fileNameForFacePhoto = 'Face photo.jpg';
        String fileNameForBodyPhoto = 'Body photo.jpg';
        //Set attributes for face photo
        
        //First we upload the face photo
        
        //Convert the string facePhoto into a Blob file to simulate that is a File
        testAttachmentFace.Body = Blob.valueOf(facePhoto);
        
        testAttachmentFace.Name = 'Test face photo.jpg';
        testAttachmentFace.ParentId = testAccount.Id;
        controller.facePhoto = Blob.valueOf(facePhoto);
        controller.fileNameForFacePhoto = fileNameForFacePhoto;
        
        
        //Let´s sure that we get the message of extension when the extension of file is diferent from allowed ones
        controller.fileNameForFacePhoto = 'Invalid extension.doc';
        controller.attFace = testAttachmentFace;
        controller.uploadFacePhoto();
        
        
        //We say that the attachment corresponds to the controller and give a valid extension to file
        controller.fileNameForFacePhoto = fileNameForFacePhoto;
        controller.attFace = testAttachmentFace;
        
		
        //Then we upload the attachment
        controller.uploadFacePhoto();
        
        //First we upload the body photo
        
        //Convert the string bodyPhoto into a Blob file to simulate that is a File
        testAttachmentBody.Body = Blob.valueOf(bodyPhoto);
        
        testAttachmentBody.Name = 'Test body photo.jpg';
        testAttachmentBody.ParentId = testAccount.Id;
        controller.bodyPhoto = Blob.valueOf(bodyPhoto);
        controller.fileNameForBodyPhoto = fileNameForBodyPhoto;
        
         //Let´s sure that we get the message of extension when the extension of file is diferent from allowed ones
        controller.fileNameForBodyPhoto = 'Invalid extension.doc';
        controller.attBody = testAttachmentBody;
        controller.uploadBodyPhoto();
        
        //We say that the attachment corresponds to the controller
        controller.fileNameForBodyPhoto = fileNameForBodyPhoto;
        controller.attBody = testAttachmentBody;
        
        
        //Then we upload the attachment
        controller.uploadBodyPhoto();
        
        //Go to the next Step of the wizard
        nextPage = controller.goToStep7();
        
        //Specify that the current page
        Test.setCurrentPage(nextPage);
        
        //In this step, the user introduces information about education, so go ahead and Let´s do it
        
        //First, We produce an exception in method saveEducation and cover the code
        Education__c eduEmpty;
        controller.education = eduEmpty;
        controller.saveEducation();
        
        //Now, the normal flow
        Education__c testEducation = new Education__c();
        Education__c testEducationEmpty = new Education__c();
        testEducation.Study_Level__c = 'University';
        testEducation.Title__c = 'Test Title';
        testEducation.Institution_Name__c = 'Test Institution';
        controller.education = testEducation;
        
        //Let´s sure that method saveEducation doesn´t work if we send an empty object Commute__c 
        //In this way, we ensure that will cover the code that sends the messages to the user
        
        //First the message for Study_level
        //ApexPages.addMessage(new Apexpages.Message(ApexPages.Severity.ERROR, 'Please. Select a value in Study level field'));
        controller.education = testEducationEmpty;
        controller.saveEducation();
        
        //Then, the message for Title
        //ApexPages.addMessage(new Apexpages.Message(ApexPages.Severity.ERROR, 'Please. Enter a value in Title field'));
        testEducationEmpty.Study_Level__c = 'University';
        controller.education = testEducationEmpty;
        controller.saveEducation();
        
        //Assign the testEducation object to the controller because in next steps we update. In this way we avoid
        //an exception
        controller.education = testEducation;
        
        
        //Let´s sure that a message is sent to the user if To and From Dates are equal
        testEducation.From__c = Date.parse('13/12/1990');
        testEducation.To__c = Date.parse('13/12/1990');
        controller.saveEducation();
        
         //Let´s sure that a message is sent to the user if From Date is greater than To Date
        testEducation.From__c = Date.parse('05/10/2000');
        testEducation.To__c = Date.parse('15/09/1996');
        controller.saveEducation();
        
         //Let´s sure that a message is sent to the user if To Date is greater than current date
        testEducation.From__c = Date.parse('13/12/1990');
        testEducation.To__c = Date.parse('13/12/2012');
        controller.saveEducation();
        
        //Now we introduce valid dates and save the education
        testEducation.From__c = Date.parse('01/08/2010');
        testEducation.To__c = Date.parse('15/05/2012');
        controller.saveEducation();
        
         //We produce an exception in method updateEducation to cover the code
        AccountStandardController.updateEducation('', 'Study_level__c', 'Santa Fe');
       
        //Now update some information of the education already saved
        AccountStandardController.updateEducation(testEducation.Id, 'Study_level__c', 'High School');
        AccountStandardController.updateEducation(testEducation.Id, 'Title__c', 'Test Title updated');
        AccountStandardController.updateEducation(testEducation.Id, 'Institution_Name__c', 'Test Institution updated');
        AccountStandardController.updateEducation(testEducation.Id, 'From__c', '01/08/2010');
        AccountStandardController.updateEducation(testEducation.Id, 'To__c', '15/05/2012');
        
        //We produce an exception to cover the code of method deleteEducation()
  		//AccountStandardController.deleteEducation('');
        
        //Now, We delete correctly the education to complete ABC code coverage for education object
        //AccountStandardController.deleteEducation(testEducation.Id);
        ApexPages.currentPage().getParameters().put('idEducationToDelete',testEducation.Id);
        AccountStandardController.deleteEducation();
        
        //Now, we go to the next step of the wizard
        nextPage = controller.goToStep8();
        
        //Test has to know what is the current page
        Test.setCurrentPage(nextPage);
        
        //In Step 8, user gives information about Work history, so go ahead and Let´s do it.
        
        //First, We produce an exception in method saveWorkHistory and cover the code
        Work_History__c worEmpty;
        controller.history = worEmpty;
        controller.saveWorkHistory();
        
        //Now, the normal flow
        //Create a Work_History__c object for testing
        Work_History__c testWorkHistory = new Work_History__c();
        Work_History__c testWorkHistoryEmpty = new Work_History__c();
        testWorkHistory.Company__c = 'Test Company';
        testWorkHistory.Position__c = 'Test Position';
        testWorkHistory.Seniority_yrs__c = 1;
        testWorkHistory.Reason_for_leaving__c = 'Test Reason';
        
        //Let´s sure that method saveEducation doesn´t work if we send an empty object Work_History__c 
        //In this way, we ensure that will cover the code that sends the messages to the user
        
        //First the message for Company
        //ApexPages.addMessage(new Apexpages.Message(ApexPages.Severity.ERROR, 'Please. Enter a value in Company field'));
        controller.history = testWorkHistoryEmpty;
        controller.saveWorkHistory();
        
        //Then, the message for Position__c
        //ApexPages.addMessage(new Apexpages.Message(ApexPages.Severity.ERROR, 'Please. Enter a value in Position field'));
        testWorkHistoryEmpty.Company__c = 'Test132';
        controller.history = testWorkHistoryEmpty;
        controller.saveWorkHistory();
        
        
        //We assign the testWorkHistory to controller
        controller.history = testWorkHistory;
        
        //Save the Work_History__c
        controller.saveWorkHistory();
        
         //We produce an exception in method updateWorkHistory to cover the code
        AccountStandardController.updateWorkHistory('', 'Company__c', 'Testing');
        
        //Now we update some information of the Work_History__c object already saved
        AccountStandardController.updateWorkHistory(testWorkHistory.Id, 'Company__c', 'Test Company updated');
        AccountStandardController.updateWorkHistory(testWorkHistory.Id, 'Position__c', 'Test Position updated');
        AccountStandardController.updateWorkHistory(testWorkHistory.Id, 'Seniority_yrs__c', '2');
        AccountStandardController.updateWorkHistory(testWorkHistory.Id, 'Seniority_yrs__c', '');
        AccountStandardController.updateWorkHistory(testWorkHistory.Id, 'Reason_for_living', 'Test Reason updated');
        
        //We produce an exception to cover the code of method deleteWorkHistory()
  		//AccountStandardController.deleteWorkHistory('');
         
        //Once done the update, delete the Work_History__c
        //AccountStandardController.deleteWorkHistory(testWorkHistory.Id);
        ApexPages.currentPage().getParameters().put('idWorkHistoryToDelete',testWorkHistory.Id);
        AccountStandardController.deleteWorkHistory();
        
        //Finally, we finish the wizard
        controller.finish();
        
        //We produce an exception sending an empty employee to the method cancel
        Account emptyToCancel;
        controller.personAccount = emptyToCancel;
        controller.cancel();
        
        //We use the cancel methosd to cover its code
        controller.personAccount = testAccount;
        controller.cancel();
                
               
        
    }
}